import React from 'react'

export default class BindThis extends React.Component{
    constructor(){
        super()
        this.state = {
            msg:'默认的msg'
        }
        /**
         * 当调用bind改变this指向后，调用的结果有一个返回值，这个返回值是改变this指向后的函数的引用
         * bind本质上不是修改原函数this的指向
         * 
        */
        this.changeMsg2 = this.changeMsg2.bind(this,'🚴','🚄')
        
    }
    render(){
        return <div>
            <h1>绑定this传参的几种方式</h1>
            <input type="button" value="使用call绑定this并传参的方式1" onClick={this.changeMsg1.bind(this,"嘿嘿","嘻嘻")}/>
            <input type="button" value="使用call绑定this并传参的方式2" onClick={this.changeMsg2}/>
            <input type="button" value="使用call绑定this并传参的方式3" onClick={()=>this.changeMsg3('😆','😋')}/>
            <br/>
            <div>{this.state.msg}</div>
            {/* 
                React中没有指令的概念，所以React也默认也不支持双向数据绑定
                只支持把数据从 state 绑定到页面，但是无法自动实现数据从页面传输到 state 中去，
                react不支持数据的自动逆向传输
                如果为表单元素绑定了value属性，那么必须同时提供一个 readOnly属性 或者 onChange 事件

            */}
            <input ref='txt' type="text" style={{width:'100%'}} value={this.state.msg} onChange={this.txtChanged.bind(this)}/>
        </div>
    }


    txtChanged(e){
        /**
         * 获取文本框的值三种方式
         * document.getElementById
         * 使用ref获取 this.refs.txt.value
         * 使用e.target.value获取（e.target表示触发这个事件事件源对象，原生的 JS DOM 对象）
         * 
        */
        console.log(e.target.value);
        
        this.setState({
            msg:e.target.value
        })
    }

    /**
     * 方式1
     * 作为普通方法调用，此处的this是undefined的
     * 调用的时候使用bind()绑定this,bind可以修改内部tihs的指向
     * bind与call、apply区别在于，后者会立即调用前边绑定的函数，而bind只是修改this指向，并不会立即调用
     * bind第一个参数是用来修改前边函数的this指向，之后每一个参数都是绑定前边调用函数的实际参数
     * 
    */
    changeMsg1(arg1,arg2){
        this.setState({
            msg:`哈哈${arg1}${arg2}`
        })
    }


    /**
     * 方式2
     * 当调用bind改变this指向后，调用的结果有一个返回值，这个返回值是改变this指向后的函数的引用
     * bind本质上不是修改原函数this的指向     * 
     * 
    */
    changeMsg2(arg1,arg2){
        this.setState({
            msg:`哈哈${arg1}${arg2}`
        })
    }


    /**
     * 方式3
     * 箭头函数
    */
   changeMsg3 = (arg1,arg2)=>{
        this.setState({
            msg:`哈哈${arg1}${arg2}`
        })
   }
} 
